<?php

namespace app\api\controller;

use app\api\model\Address;
use app\api\model\Config;
use app\api\model\Posts;
use app\api\model\Postsaux;
use app\api\model\Users;
use app\api\model\BonusUsers;
use app\api\model\Splicing;
use app\api\model\Splicingorder as SplicingorderModel;
use app\api\model\SplicingorderGoods;
use app\api\model\UsersMoneylog;
use app\common\model\Wechatpay;


require_once VENDOR_PATH.'Wxpay/lib/WxPay.Api.php';
require_once VENDOR_PATH.'Wxpay/example/WxPay.JsApiPay.php';

class Splicingorder extends Api
{
    protected $noNeedLogin = ['order_payUrl'];
    protected function _initialize()
    {
        parent::_initialize(); // TODO: Change the autogenerated stub
    }

    //拼单首页(列表)
    public function splicing_list(){
        $lat = input('lat',''); //坐标纬度
        $lng = input('lng',''); //坐标经度
        if(empty($lat) || empty($lng)){
            return_msg(1,'请先允许位置授权');
        }

        //查询所有的拼团信息
        $where['endtime'] = ['>=',time()];
        $where['is_open'] = ['=',1];
        $where['status'] = ['in',['0','1']];
        $field = "id,num,address,lat,lng,endtime,users_id";
        $lists = Splicing::where($where)->field($field)->order("id desc")->select();
        //位置匹配
        $splicing_distance = Config::getValue(['name'=>'splicing_distance']);
        $splicing_list = [];
        foreach($lists as $v){
            $distance = host_getDistance($lat,$lng,$v['lat'],$v['lng']);
            if($distance <= $splicing_distance){
                $v['is_own'] = 0;
                if($v['users_id'] == $this->userInfo['id']){
                    $v['is_own'] = 1;
                }
                $v['surplus'] = $v['endtime']-time();
                $v['distance'] = bcadd($distance,0,1);
                if($v['surplus'] > 0){
                    $splicing_list[] = $v;
                }
            }
        }
        $splicing_times = Config::getValue(['name'=>'splicing_times']);
        $return = [
            'start_send'            =>      5,//起送量   暂定5份起送
            'splicing_times'        =>      $splicing_times, //拼单时间
            'splicing_list'         =>      $splicing_list
        ];
        return_msg(0,'查询成功',$return);
    }

    //拼单确认订单
    public function splicing_confirm(){
        $posts_id = input('id',''); //套餐ID
        $aux = input('aux','');     //附加项
        $num = input('num',1);      //订餐数
        $address_id = input('address_id',''); //收货地址ID(发起拼单时传入)
        $splicing_id = input('splicing_id',''); //拼单ID(加入拼单时传入)
        //参数验证
        if(empty($posts_id)){
            return_msg(1,'参数错误：请传入套餐ID！');
        }

        if(!empty($address_id)){
            //查询收货地址
            $address = Address::where(['id'=>$address_id])->field("address,lat,lng,address_complete")->find();
        }else{
            if(!empty($splicing_id)){
                $address = Splicing::where(['id'=>$splicing_id])->field("address,lat,lng,address_complete")->find();
            }else{
                return_msg(1,'参数错误：请传入收货地址ID或拼单ID！');
            }
        }

        $posts = Posts::where(['id'=>$posts_id,'status'=>'1','del'=>0])->field("id,name,date,image,price,content")->find();
        if(empty($posts)){
            return_msg(1,'该套餐已下架！');
        }
        $endtime = Config::getValue(['name'=>'endtime'],'value');//下单结束时间
        if(time() > strtotime($posts['date'].' '.$endtime)){
            //当天订餐时间已过
            return_msg(1,'当天订餐时间已过,无法订餐哦');
        }
        $auxList = [];
        if(!empty($aux)){
            $auxList = json_decode($aux,true);
        }

        $postsList = [];
        $moneys = 0;
        for($i=0;$i<$num;$i++){
            $moneys += $posts['price'];
            $posts_aux = isset($auxList[$i])?$auxList[$i]:[];
            $posts_auxList = [];
            if(!empty($posts_aux)){
                $posts_aux_ids = array_column($posts_aux,'id');
                //查询附加项
                $posts_auxList = Postsaux::where(['id'=>['in',$posts_aux_ids]])->field("id,name,price")->select();
                $posts_auxList = collection($posts_auxList)->toArray();
                foreach($posts_auxList as $v2){
                    $moneys += $v2['price'];
                }
            }
            $data = [
                'posts' =>  [
                    'id'        =>      $posts['id'],
                    'name'      =>      $posts['name'],
                    'price'     =>      $posts['price']
                ],
                'posts_aux' =>  $posts_auxList
            ];
            $postsList[] = $data;
        }
        //查询可用优惠券
        $where = [
            'bu.users_id'   =>  $this->userInfo['id'],
            'bu.endtime'    =>  ['>=',time()]
        ];
        $field = "bu.id,bu.num,bu.ynum,bu.endtime,b.name,b.postsaux_id,b.type,b.bonus_money";
        $bonus = BonusUsers::getList($where,$field,1,999);
        $bonusList = [];
        if(!empty($bonus['list'])){
            //查询附加项
            $postsaux = Postsaux::column('price','id');
            foreach($bonus['list'] as $key=>$val){
                if($val['num'] <= 0){
                    continue;
                }
                if($val['type'] == 1){
                    //满减券
                    if($moneys >= $val['money']){
                        $bonusList[] = $val;
                    }
                }else{
                    //计算可抵扣金额
                    $val['bonus_money'] = isset($postsaux[$val['postsaux_id']])?$postsaux[$val['postsaux_id']]:0;
                    $bonusList[] = $val;
                }
            }
        }

        $return = [
            'users_money'   =>      $this->userInfo['money'],//用户余额
            'address_id'    =>      $address_id,
            'splicing_id'   =>      $splicing_id,
            'posts_id'      =>      $posts_id,  //套餐ID
            'num'           =>      $num,       //购买数量
            'aux'           =>      $aux,       //所选附加项
            'address'       =>      $address,    //收货地址信息
            'moneys'        =>      strval($moneys),    //总金额
            'posts_list'    =>      $postsList, //套餐信息
            'bonus_list'    =>      $bonusList  //优惠券信息
        ];
        return_msg(0,'查询成功',$return);
    }

    //提交订单(拼单)
    public function splicing_addorder(){
        $posts_id = input('id',''); //套餐ID
        $aux = input('aux','');     //附加项
        $num = input('num',1);      //订餐数
        $bonus_id  = input('bonus_id',0);   //优惠券ID
        $pay_type  = input('pay_type',1);   //支付方式:1=微信支付,2=余额支付
        $address_id = input('address_id',''); //收货地址ID(发起拼单时传入)
        $splicing_id = input('splicing_id',''); //拼单ID(加入拼单时传入)
        $name = input('name','');   //联系人
        $phone = input('phone','');   //联系方式
        //参数验证
        if(empty($posts_id)){
            return_msg(1,'参数错误：请传入套餐ID！');
        }

        if(!empty($address_id)){
            //查询收货地址
            $address = Address::where(['id'=>$address_id,'users_id'=>$this->userInfo['id']])->field("name,phone,address,lat,lng,address_complete")->find();
            if(empty($address)){
                return_msg(1,'参数错误：收货地址不存在！');
            }
            $name = $address['name'];
            $phone = $address['phone'];

            //距离判断
            //坐标
            $shop_lng = '113.379457';
            $shop_lat = '23.121751';
            $distancess = Config::getValue(['name'=>'distance']);
            $distance2 = host_getDistance($address['lat'],$address['lng'],$shop_lat,$shop_lng);
            if($distance2 > $distancess){
                return_msg(1,'当前位置距离商家超出 '.$distancess.' 米,无法发起拼单哦');
            }

        }else{
            if(!empty($splicing_id)){
                if(empty($name)){
                    return_msg(1,'请输入联系人');
                }
                if(empty($phone)){
                    return_msg(1,'请输入联系方式');
                }
                $address = Splicing::where(['id'=>$splicing_id,'is_open'=>1])->field("users_id,address,lat,lng,address_complete")->find();
                if(empty($address)){
                    return_msg(1,'未查到该拼单信息');
                }
                if($address['users_id'] == $this->userInfo['id']){
                    return_msg(1,'您不可以加入自己的拼单哦');
                }
            }else{
                return_msg(1,'参数错误：请传入收货地址ID或拼单ID！');
            }
        }
        if(empty($address)){
            return_msg(1,'参数错误：收货地址ID或拼单ID错误！');
        }
        $posts = Posts::where(['id'=>$posts_id,'status'=>'1','del'=>0])->field("id,name,date,image,price,content")->find();
        if(empty($posts)){
            return_msg(1,'该套餐已下架！');
        }
        $endtime = Config::getValue(['name'=>'endtime'],'value');//下单结束时间
        if(time() > strtotime($posts['date'].' '.$endtime)){
            //当天订餐时间已过
            return_msg(1,'当天订餐时间已过,无法订餐哦');
        }
        $auxList = [];
        if(!empty($aux)){
            $auxList = json_decode($aux,true);
        }
        $postsList = [];
        $moneys = $auxmoneys = 0;
        for($i=0;$i<$num;$i++){
            $moneys += $posts['price'];
            $posts_aux = isset($auxList[$i])?$auxList[$i]:[];
            $posts_auxList = [];
            $aux_money = 0;
            if(!empty($posts_aux)){
                $posts_aux_ids = array_column($posts_aux,'id');
                //查询附加项
                $posts_auxList = Postsaux::where(['id'=>['in',$posts_aux_ids]])->field("id,name,price")->select();
                $posts_auxList = collection($posts_auxList)->toArray();
                foreach($posts_auxList as $v2){
                    $moneys += $v2['price'];
                    $aux_money += $v2['price'];
                    $auxmoneys += $v2['price'];
                }
            }
            $data = [
                'posts_id'      =>  $posts['id'],
                'posts_price'   =>  $posts['price'],
                'name'          =>  $posts['name'],
                'aux'           =>  json_encode($posts_auxList),
                'aux_money'     =>  $aux_money,
                'image'         =>  $posts['image'],
            ];
            $postsList[] = $data;
        }
        //查询优惠金额
        $bonus_money = 0;
        if(!empty($bonus_id)){
            $bonus_field = "bu.id,bu.num,bu.ynum,bu.endtime,b.name,b.postsaux_id,b.type,b.bonus_money";
            $bonus = BonusUsers::getInfo(['bu.id'=>$bonus_id,'bu.users_id'=>$this->userInfo['id']],$bonus_field);
            if(empty($bonus)){
                return_msg(1,'该优惠券暂不可用！');
            }
            if($bonus['endtime'] < time()){
                return_msg(1,'该优惠券已过期,无法使用！');
            }
            if($bonus['num'] <= 0){
                return_msg(1,'该优惠券已用完,无法使用！');
            }
            if($bonus['type'] == 1){
                //满减券
                if($moneys >= $bonus['money']){
                    $bonus_money = $bonus['bonus_money'];
                }else{
                    return_msg(1,'该优惠券需满'.$bonus['money'].'元才能使用！');
                }
            }else{
                //计算可抵扣金额
                $bonus_money = Postsaux::where(['id'=>$bonus['postsaux_id']])->value('price');
            }
        }
        $splicing_times = Config::getValue(['name'=>'splicing_times']);
        //拼单表
        if(!empty($address_id)){
            //说明是发起拼单
            $splicingAddData = [
                'users_id'      =>      $this->userInfo['id'],
                'num'           =>      $num,
                'address'       =>      $address['address'],
                'lat'           =>      $address['lat'],
                'lng'           =>      $address['lng'],
                'addtime'       =>      time(),
                'endtime'       =>      time()+$splicing_times*60,
                'address_id'    =>      $address_id,
                'name'          =>      $address['name'],
                'phone'         =>      $address['phone'],
                'address_complete'         =>      $address['address_complete'],
                'date'          =>      $posts['date']
            ];
            $splicing_id = Splicing::insertGetId($splicingAddData);
        }

        $orders = [
            'splicing_id'   =>      $splicing_id,
            'order_sn'      =>      get_trade_no(),
            'users_id'      =>      $this->userInfo['id'],
            'date'          =>      $posts['date'],
            'money'         =>      $moneys-$bonus_money,
            'posts_id'      =>      $posts_id,
            'num'           =>      $num,
            'aux'           =>      json_encode($auxList),
            'bonus_id'      =>      $bonus_id,
            'bonus'         =>      $bonus_money,
            'posts_money'   =>      $posts['price'],
            'aux_money'     =>      $auxmoneys,
            'address'       =>      $address['address'],
            'lat'           =>      $address['lat'],
            'lng'           =>      $address['lng'],
            'name'          =>      $name,
            'phone'         =>      $phone,
            'addtime'       =>      time(),
            'posts_name'    =>      $posts['name'],
            'posts_image'   =>      $posts['image'],
            'pay_type'      =>      strval($pay_type),
            'address_complete'  =>  $address['address_complete'],
        ];

        if($pay_type == 2){
            //余额支付
            if($this->userInfo['money'] < $orders['money']){
                return_msg(1,'您的余额不足,请选择其他支付方式！');
            }
        }
        $order_id = SplicingorderModel::insertGetId($orders);
        foreach($postsList as &$val){
            $val['order_id'] = $order_id;
        }
        SplicingorderGoods::insertAll($postsList);
        //更新优惠券
        if(!empty($bonus_id)){
            BonusUsers::where(['id'=>$bonus_id])->setInc('ynum',1);
        }
        if($pay_type == 1){
            //拉起支付
            $input = new \WxPayUnifiedOrder();
            $input->SetBody('拼单');
            $input->SetAttach('拼单');
            $input->SetOut_trade_no($orders['order_sn']);
            $input->SetTotal_fee($orders['money']*100);
            $input->SetTime_start(date("YmdHis"));
            $input->SetTime_expire(date("YmdHis", time() + 600));
            $payReturn = 'http://'.$_SERVER['HTTP_HOST'].url('Splicingorder/order_payUrl');
            $input->SetOpenid($this->userInfo['openid']);
            $input->SetNotify_url($payReturn);
            $input->SetTrade_type("JSAPI");
            $order = \WxPayApi::unifiedOrder($input);
            if($order['return_msg']=="OK"){
                $tools = new \JsApiPay();
                $jsApiParameters = $tools->GetJsApiParameters($order);
                $jsApiParameters['mch_id'] = $order['mch_id'];
                $jsApiParameters['prepay_id'] = $order['prepay_id'];
                return_msg(0,'微信支付调用成功',['order_id'=>$order_id,'money'=>strval($orders['money']),'pat_status'=>0,'pay'=>$jsApiParameters]);
            }else{
                return_msg(1,'微信支付调用失败');
            }
        }else{
            //余额支付  扣除余额,更改订单状态
            Users::where(['id'=>$this->userInfo['id']])->setDec('money',$orders['money']);
            //生成余额记录
            $log = [
                'users_id'      =>      $this->userInfo['id'],
                'money'         =>      -$orders['money'],
                'type'          =>      3,
                'date'          =>      date("Y-m-d"),
                'addtime'       =>      time(),
                'desc'          =>      '拼单： '.$posts['name'],
                'order_id'      =>      $order_id
            ];
            UsersMoneylog::insert($log);
            SplicingorderModel::where(['id'=>$order_id])->update(['order_status'=>'1','pay_time'=>time()]);
            $Splicing_users_id = Splicing::where(['id'=>$orders['splicing_id']])->value('users_id');
            if($Splicing_users_id == $orders['users_id']){
                //拼单发起人是自己
                Splicing::where(['id'=>$orders['splicing_id']])->update(['is_open'=>1]);
            }else{
                //拼单数量 +1
                Splicing::where(['id'=>$orders['splicing_id']])->setInc('num',$orders['num']);
            }

            return_msg(0,'余额支付成功',['order_id'=>$order_id,'money'=>strval($orders['money']),'pat_status'=>1]);
        }

    }

    //支付回调
    public function order_payUrl()
    {
        controller('Splicingnotify')->Handle(false);
    }


    //拼单-订单列表
    public function splicing_order_list(){
        //默认进行中
        $type = input('type',1);//1=进行中,2=历史订单
        $page = input('page',1);
        $limit = input('limit',10);
        $where['users_id'] = $this->userInfo['id'];
        if($type == 1){
            //进行中
            $where['order_status'] = 1;
        }else{
            $where['order_status'] = ['not in',[0,1,3]];
        }
        $date = input('date','');
        if(!empty($date)){
            $start_time = strtotime($date);
            $end_time = strtotime($date.' 23:59:59');
            $where['addtime'] = ['between',[$start_time,$end_time]];
        }

        $field = "id,order_sn,splicing_id,order_status,money,address,lat,lng,posts_name,posts_image,addtime,name,phone,address_complete,is_invoice,is_refund";
        $return = SplicingorderModel::getList($where,$field,$page,$limit);

        $tcphone = Config::getValue(['name'=>'tcphone']);
        return_msg(0,'查询成功',['tcphone'=>$tcphone,'total'=>$return['total'],'page'=>$page,'list'=>$return['list']]);
    }

    //拼单-订单详情
    public function splicing_order_info(){
        $id = input('id',0);    //订单ID
        $field = "id,order_sn,order_status,money,address,lat,lng,addtime,name,phone,bonus,bonus_id,address_complete";
        $order = SplicingorderModel::where(['id'=>$id,'users_id'=>$this->userInfo['id']])->field($field)->find();
        if(empty($order)){
            return_msg(1,'参数错误：订单不存在！');
        }
        $goodsList = SplicingorderGoods::where(['order_id'=>$id])->field('posts_id,name,posts_price,aux,aux_money')->select();
        $goods_moneys = 0;
        foreach($goodsList as $v){
            $goods_moneys += $v['posts_price'];
            $goods_moneys += $v['aux_money'];
            $v['aux'] = json_decode($v['aux'],true);
        }
        $bonus = [];
        if(!empty($order['bonus_id'])){
            $bonus_field = "bu.id,b.name,b.type,b.bonus_money";
            $bonus = BonusUsers::getInfo(['bu.id'=>$order['bonus_id']],$bonus_field);
        }
        $order['addtime'] = date("Y-m-d H:i:s",$order['addtime']);
        $order['bonuslist'] = $bonus;
        $order['goods_amount'] = strval($goods_moneys);
        $order['order_goods'] = $goodsList;
        return_msg(0,'查询成功',$order);
    }

    //拼单-取消订单
    public function splicing_order_cancel(){
        $id = input('id','');//订单id
        $field = "id,splicing_id,order_sn,order_status,num,posts_name,money,pay_type";
        $order = SplicingorderModel::where(['id'=>$id,'users_id'=>$this->userInfo['id']])->field($field)->find();
        if(empty($order)){
            return_msg(1,'参数错误：订单不存在！');
        }
        if($order['order_status'] == 3){
            return_msg(1,'该订单已取消');
        }
        $splicing = Splicing::where(['id'=>$order['splicing_id']])->find();
        if($splicing['status'] == 1){
            return_msg(1,'该拼单已成团,不可取消');
        }
        //修改订单状态
        SplicingorderModel::where(['id'=>$id,'users_id'=>$this->userInfo['id']])->update(['order_status'=>3]);
        if($order['order_status'] == 1){
            //订单已支付  退款
            if($order['pay_type'] == 1){
                //微信支付
                //退款
                $wx     = new Wechatpay();
                $cancel = $wx->refund($order['order_sn'], get_trade_no(),$order['money'],$order['money']); //支付单号
            }else{
                //余额支付  返回余额,更改拼团表
                Users::where(['id'=>$this->userInfo['id']])->setInc('money',$order['money']);
                //生成余额记录
                $log = [
                    'users_id'      =>      $this->userInfo['id'],
                    'money'         =>      $order['money'],
                    'type'          =>      4,
                    'date'          =>      date("Y-m-d"),
                    'addtime'       =>      time(),
                    'desc'          =>      '拼单取消： '.$order['posts_name'],
                    'order_id'      =>      $order['id']
                ];
                UsersMoneylog::insert($log);
            }
            //拼单数量 -1
            Splicing::where(['id'=>$order['splicing_id']])->setDec('num',$order['num']);
            $splicing_num = Splicing::where(['id'=>$order['splicing_id']])->value('num');
            if($splicing_num <= 0){
                Splicing::where(['id'=>$order['splicing_id']])->update(['status'=>'2']);
            }
        }
        return_msg(0,'操作成功');
    }
}